'use strict'

process.chdir(__dirname)

const titbit = require('titbit')
const fs = require('fs')
const pg = require('pg')
const dbconfig = require('./dbconfig.js')
const wxkey = require('./wxkey.js')

const token = require('titbit-token')

let tok = new token({
  //token有效期，单位是秒
  expires: 30,
  
  //必须是32位字母数字
  key: '1qaz2wsx3edc4rfv5tgb6yhn7ujmki89',

  //必须是16位字母数字
  iv: '9io08u7y6t5r4e3w'
})

//使用HTTP/1.1的客户端
const {httpcli} = require('gohttp')

//初始化数据库连接
let psql = new pg.Pool(dbconfig)

try {
  fs.accessSync('./images')
} catch (err) {
  fs.mkdirSync('./images')
}

let cert_path = '/usr/local/cert'

const app = new titbit({
  //开启调试模式，会输出错误信息。
  debug: true,
  globalLog: true,
  cert: `${cert_path}/www.vvh5.com.pem`,
  key: `${cert_path}/www.vvh5.com.key`
})

/** ---------------content 路由----------------- */

app.get('/content', async c => {
  let sqltext = 'SELECT id,title,update_time FROM content'
  let r = await psql.query(sqltext)

  c.send( r.rows )
})

app.post('/content', async c => {
    try {
      //c.body是提交的请求体数据。
      let data = JSON.parse(c.body)
      let sqltext = 'INSERT INTO content'
          + '(id, detail, title, add_time, update_time)'
          + ' VALUES($1, $2, $3, $4, $5)'

      //随机数转成16进制字符串并去掉前两位，字串作为ID。
      let id = Math.random().toString(16).substring(2)
      let tm = Date.now()

      let r = await psql.query(sqltext, [
        id, data.detail, data.title, tm, tm
      ])

      if (r.rowCount === 0) {
        return c.status(500).send('failed')
      }

      c.send(id)

    } catch (err) {
      console.error(err)
      c.status(400).send('bad data')
    }
})

app.get('/content/:id', async c => {
  let id = c.param.id

  let sqltext = 'SELECT id,detail,title,update_time '
      + ' FROM content WHERE id=$1';

  let r = await psql.query(sqltext, [ id ])

  if (r.rowCount === 0)
      return c.status(404).send('not found');

  c.send(r.rows[0])

})

app.delete('/content/:id', async c => {
  let r = await psql.query(`DELETE FROM content WHERE id=$1`, 
          [ c.param.id ]
        )

  c.send({
    count: r.rowCount
  })

})

/** ---------------content 路由 - END - ----------------- */

//c 就是 context。
app.get('/', async c => {
  c.send('ok')
})

app.get('/upload', async c => {
  //c.helper是助手函数模块，其中有对stream.pipe的封装。
  //c.reply是响应对象，http/1.1中指向response，http/2中指向stream。
  await c.helper.pipe('./upload.html', c.reply)
})

app.post('/upload', async c => {
  let f = c.getFile('file')

  if (!f) {
    return c.status(400).send('file not found')
  }

  //生成唯一文件名
  let fname = c.helper.makeName(f.filename)

  try {
    await c.moveFile(f, `./images/${fname}`)
    c.send(fname)
  } catch (err) {
    c.status(500).send('failed')
  }

})

app.get('/image/:name', async c => {
  let imgname = c.param.name

  try {
    await c.helper.pipe(`./images/${imgname}`, c.reply)
  } catch (err) {
    c.status(404).send('image not found')
  }

})

app.get('/user/:name/:age/:mobile', async c => {
  console.log(c.param)
  c.send( c.param )
})

app.get('/mp-login/:code', async c => {
  
  let auth_url = `https://api.weixin.qq.com/sns/jscode2session`
        + `?appid=${wxkey.appid}`
        + `&secret=${wxkey.secret}`
        + `&js_code=${c.param.code}`
        + `&grant_type=authorization_code`

  let ret = await httpcli.get(auth_url)
                        .then(res => {
                          return res.json()
                        })

  c.send( tok.make(ret) )

})

//监听1234端口运行服务。
app.run(1999)
